package com.xuecheng.ucenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.ucenter.feignclient.CheckCodeClient;
import com.xuecheng.ucenter.mapper.XcUserMapper;
import com.xuecheng.ucenter.model.dto.AuthParamsDto;
import com.xuecheng.ucenter.model.dto.XcUserExt;
import com.xuecheng.ucenter.model.po.XcUser;
import com.xuecheng.ucenter.service.AuthService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

/**
 * 账户名密码方式
 */
@Service("password_authService")
@RequiredArgsConstructor
public class PasswordAuthServiceImpl implements AuthService {

    private final XcUserMapper xcUserMapper;

    private final PasswordEncoder passwordEncoder;

    private final CheckCodeClient checkCodeClient;

    @Override
    public XcUserExt execute(AuthParamsDto authParamsDto) {
        // 获取账号
        String username = authParamsDto.getUsername();

        // 获取输入的验证码
        String checkCode = authParamsDto.getCheckcode();
        // 获取验证码对应的key
        String checkCodeKey = authParamsDto.getCheckcodekey();

        if (StringUtils.isEmpty(checkCode) || StringUtils.isEmpty(checkCodeKey)) {
            throw new RuntimeException("请输入验证码");
        }

        // 远程调用验证码服务去校验验证码是否正确
        Boolean verify = checkCodeClient.verify(checkCodeKey, checkCode);
        if (verify == null || !verify) {
            throw new RuntimeException("验证码输入错误");
        }

        // 账号是否存在
        // 根据username查询数据库
        XcUser xcUser = xcUserMapper.selectOne(new LambdaQueryWrapper<XcUser>().eq(XcUser::getUsername, username));
        // 查询到用户不存在，返回null即可 spring security框架会自动抛出异常
        if (xcUser == null) {
            throw new RuntimeException("账号不存在");
        }

        // 校验密码是否正确
        // 如果查到了用户就可以拿到正确的密码
        String passwordDb = xcUser.getPassword(); // 数据库的密码
        // 拿到用户输入的密码
        String passwordForm = authParamsDto.getPassword();
        // 校验密码  第一个参数是用户输入的密码 第二个参数是数据库中加密的密码
        boolean matches = passwordEncoder.matches(passwordForm, passwordDb);
        if (!matches) {
            throw new RuntimeException("账号或者密码错误");
        }

        XcUserExt xcUserExt = new XcUserExt();
        BeanUtils.copyProperties(xcUser, xcUserExt);
        return xcUserExt;
    }
}
